#include <string.h>
#include <err.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <assert.h>

#include "bstrlib.h"
#include "fd_list.h"


struct sfd_server{
    int n_fd;
    int cmd;
    bool new_file;
    bool start_over;
    bool cont;
    bool recv;
    bool send;
    bstring file;
    char* recv_str;
    char** diff_filenames;
    int amount;
    int transferred;
    int metadata;
    int related;
    int port;
    int response;
};

struct sfd_item{
    int n_fd;
    int cmd;
    bool atnd;
    bool recv;
    bool fst_time;
    char* filename;
    char* recv_str;
    int offset;
    int amount;
    int transferred;
    int related;
    int port;
};

struct sfd_list{
    fd_item *item;
    fd_server *server;
    int size;
    int server_size;
};

fd_server
fd_server_create(void){
    struct sfd_server *server;

    server = calloc(1, sizeof(struct sfd_server));
    server->n_fd=-1;
    server->cmd=-1;
    server->new_file=true;
    server->cont=false;
    server->send=true;
    server->recv=false;
    server->file=bfromcstr("");
    server->recv_str=calloc(1,sizeof(char));
    if (server->recv_str == NULL){
        perror("calloc");
        return NULL;
    }
    strcpy(server->recv_str, "");
    server->diff_filenames=calloc(1,sizeof(char*));
    if (server->diff_filenames == NULL){
        perror("calloc");
        return NULL;
    }
    server->amount=0;
    server->transferred=-1;
    server->metadata=-1;
    server->related=-1;
    server->port=-1;
    server->response=-1;
    return server;
}

void
fd_server_set_new_file(fd_server server){
    server->new_file = true;
}

bool
fd_server_get_new_file(fd_server server){
    return server->new_file;
}

void
fd_server_clear_new_file(fd_server server){
    server->new_file = false;
}

void
fd_server_set_response(fd_server server, int response){
    server->response = response;
}

int
fd_server_get_response(fd_server server){
    return server->response;
}

void
fd_server_set_port(fd_server server, int port){
    server->port = port;
}

int
fd_server_get_port(fd_server server){
    return server->port;
}

void
fd_server_set_fd(fd_server server, int fd){
    server->n_fd = fd;
}

int
fd_server_get_fd(fd_server server){
    return server->n_fd;
}

void
fd_server_set_cmd(fd_server server, int cmd){
    server->cmd = cmd;
}

int
fd_server_get_cmd(fd_server server){
    return server->cmd;
}

void
fd_server_receive(fd_server server){
    server->cont=true;
}

void
fd_server_stop_receiving(fd_server server){
    server->cont=false;
}

bool
fd_server_should_receive(fd_server server){
    return server->cont;
}

void
fd_server_send(fd_server server){
    server->send=true;
}

void
fd_server_not_send(fd_server server){
    server->send=false;
}

bool
fd_server_should_send(fd_server server){
    return server->send;
}

void
fd_server_clear_file(fd_server server){
    bdestroy (server->file);
    server->file = NULL;
    server->file=bfromcstr("");
}

void
fd_server_set_file(fd_server server, bstring file){
    bdestroy (server->file);
    server->file = NULL;
    server->file = bstrcpy(file);
}

bstring
fd_server_get_file(fd_server server){
    bstring file_aux=NULL;
    file_aux = bstrcpy(server->file);
    return file_aux;
}

void
fd_server_add_recv_str(fd_server server, char* string, int i){
    int old_size=0;
    assert(server != NULL);
    old_size = strlen(server->recv_str);
    server->recv_str = (char*)realloc(server->recv_str,\
                      sizeof(char)*(i+old_size+2));
    strncat(server->recv_str, string, i);
}

/*
  Obtenemos lo que hemos leido del cliente hasta ahora
*/
char*
fd_server_get_recv_str(fd_server server){
    char* string_aux=NULL;
    int size=0;
    assert(server != NULL);
    size = strlen(server->recv_str);
    string_aux = calloc(size+2, sizeof(char));
    strncpy(string_aux, server->recv_str, size);
    return string_aux;
}

void
fd_server_reset_recv_str(fd_server server){
    free(server->recv_str);
    server->recv_str=NULL;
    server->recv_str = calloc(1, sizeof(char));
    strcpy(server->recv_str, "");
}

void
fd_server_set_transferred(fd_server server, int transferred){
    server->transferred=transferred;
}

int
fd_server_get_transferred(fd_server server){
    return server->transferred;
}

void
fd_server_set_metadata(fd_server server, int metadata){
    server->metadata=metadata;
}

int
fd_server_get_metadata(fd_server server){
    return server->metadata;
}

int
fd_server_append_filename(fd_server server, char* filename){
    int size = 0;
    size = strlen(filename);
    server->diff_filenames[server->amount] = calloc(size+2, sizeof(char));
    if (server->diff_filenames[server->amount] == NULL){
        perror("calloc");
        return -1;
    }
    strncpy(server->diff_filenames[server->amount], filename, size);
    (server->amount)++;
    server->diff_filenames = (char**)realloc(server->diff_filenames,\
                             sizeof(char*)*((server->amount)+1));
    server->diff_filenames[server->amount]=NULL;
    return 1;
}

char*
fd_server_get_filename_from_list(fd_server server){
    return server->diff_filenames[0];
}

void
fd_server_swap_filename(fd_server server){
    int i=0;
    server->diff_filenames[server->amount] = server->diff_filenames[0];
    for (i=0;i<(server->amount);i++){
        server->diff_filenames[i] = server->diff_filenames[i+1];
    }
    server->diff_filenames[server->amount] = NULL;
}

void
fd_server_remove_filename_from_list(fd_server server){
    int i=0;
    free(server->diff_filenames[0]);
    for (i=0;i<(server->amount);i++){
        server->diff_filenames[i] = server->diff_filenames[i+1];
    }
    server->diff_filenames[server->amount] = NULL;
    (server->amount)--;
    server->diff_filenames = (char**)realloc(server->diff_filenames,\
                             sizeof(char*)*((server->amount)+1));
}

void
fd_server_set_relation(fd_server server, int i){
    server->related = i;
}

int
fd_server_get_relation(fd_server server){
    return server->related;
}

void
fd_server_set_recv(fd_server server, bool recv){
    server->recv = recv;
}

/*
  Informa el estado del fd, true == recibio el comando completo, 
  false == !recibio el comando completo
*/

bool
fd_server_get_recv(fd_server server){
    return (server->recv);
}

int
fd_server_get_filenames_count(fd_server server){
    return (server->amount);
}

void
fd_server_set_start_over(fd_server server){
    server->start_over=true;
}

void
fd_server_clear_start_over(fd_server server){
    server->start_over=false;
}

bool
fd_server_should_start_over(fd_server server){
    return server->start_over;
}

void
fd_server_destroy(fd_server server){
    int i=0;
    if(server->file != NULL){
        bdestroy (server->file);
        server->file = NULL;
    }
    free(server->recv_str);
    server->recv_str = NULL;
    for (i=0;i<(server->amount);i++){
        free(server->diff_filenames[i]);
        server->diff_filenames[i] = NULL;
    }
    free(server->diff_filenames);
    server->diff_filenames=NULL;
    free(server);
    server = NULL;
}

/*
  Devuelve un item vacio
*/
fd_item
fd_item_create(void){
    struct sfd_item *item;
    item = calloc(1, sizeof(struct sfd_item));
    item->n_fd=-1;
    item->cmd=-1;
    item->atnd=true;
    item->recv=false;
    item->fst_time=true;
    item->filename=calloc(1,sizeof(char));
    if (item->filename == NULL){
        perror("calloc");
        return NULL;
    }
    item->recv_str=calloc(1,sizeof(char));
    if (item->recv_str == NULL){
        perror("calloc");
        return NULL;
    }
    strcpy(item->recv_str, "");
    item->offset=-1;
    item->amount=-1;
    item->transferred=-1;
    item->related=-1;
    item->port=-1;
    return item;
}

/*
  Permite setear el numero de fd del item
*/
void
fd_item_set_fd(fd_item item, int fd){
    item->n_fd = fd;
}

/*
  Obtenemos el fd
*/
int
fd_item_get_fd(fd_item item){
    return item->n_fd;
}
/*
  Permite setear el comando pedido en el fd
  0 = get_file_listing
  1 = get_metadata
  2 = get_slice
  3 = quit
*/
void
fd_item_set_cmd(fd_item item, int cmd){
    item->cmd = cmd;
}

/*
  Obtenemos el comando con el que esta seteado el fd
*/
int
fd_item_get_cmd(fd_item item){
    return item->cmd;
}
/*
  Seteamos el campo Attended, para saber si un comando ya se finalizo de
  atender
*/
void
fd_item_set_atnd(fd_item item, bool atnd){
    item->atnd = atnd;
}

/*
  Informa sobre el estado del fd, true == atendido, false == !atentido
*/
bool
fd_item_get_atnd(fd_item item){
    return (item->atnd);
}

/*
  Seteamos el estado del fd, true == recibio el comando completo, 
  false == !recibio el comando completo
*/

void
fd_item_set_recv(fd_item item, bool recv){
    item->recv = recv;
}

/*
  Informa el estado del fd, true == recibio el comando completo, 
  false == !recibio el comando completo
*/

bool
fd_item_get_recv(fd_item item){
    return (item->recv);
}

/*
  Cargamos el nombre del archivo,
  usado en los comando get_slice y get_metadata
*/
void
fd_item_set_filename(fd_item item, char* filename){
    int size = 0;
    assert(item != NULL);
    free(item->filename);
    item->filename=NULL;
    size = strlen(filename);
    item->filename = calloc(size+2, sizeof(char));
    strncpy(item->filename, filename, size);
}

/*
  Obtenemos el nombre del archivo
*/
char*
fd_item_get_filename(fd_item item){
    char* string_aux=NULL;
    int size=0;
    assert(item != NULL);
    size = strlen(item->filename);
    string_aux = calloc(size+2, sizeof(char));
    strncpy(string_aux, item->filename, size);
    return string_aux;
}

/*
  Con esta funcion vamos cargando lo que el cliente nos
  manda
*/
void
fd_item_add_recv_str(fd_item item, char* string, int i){
    int old_size=0;
    assert(item != NULL);
    old_size = strlen(item->recv_str);
    item->recv_str = (char*)realloc(item->recv_str,\
                      sizeof(char)*(i+old_size+2));
    strncat(item->recv_str, string, i);
}

/*
  Obtenemos lo que hemos leido del cliente hasta ahora
*/
char*
fd_item_get_recv_str(fd_item item){
    char* string_aux=NULL;
    int size=0;
    assert(item != NULL);
    size = strlen(item->recv_str);
    string_aux = calloc(size+2, sizeof(char));
    strncpy(string_aux, item->recv_str, size);
    return string_aux;
}

void
fd_item_reset_recv_str(fd_item item){
    free(item->recv_str);
    item->recv_str=NULL;
    item->recv_str = calloc(1, sizeof(char));
    strcpy(item->recv_str, "");
}

/*
  Seteamos el offset del archivo pedido
*/
void
fd_item_set_offset(fd_item item, int offset){
    assert(item != NULL);
    item->offset=offset;
}

/*
  Obtenemos el offset pedido
*/
int
fd_item_get_offset(fd_item item){
    assert(item != NULL);
    return item->offset;
}

/*
  Seteamos el amount pedido
*/
void
fd_item_set_amount(fd_item item, int amount){
    item->amount=amount;
}

/*
  Obetenemos el amount pedido
*/

int
fd_item_get_amount(fd_item item){
    assert(item != NULL);
    return item->amount;
}

/*
  Aca vamos cargando cuanto ya le hemos enviado al cliente
*/
void
fd_item_set_transferred(fd_item item, int transferred){ 
    assert(item != NULL);
    item->transferred=transferred;
}

/*
  Obtenemos informacion sobre cuanto hemos enviado al cliente
*/

int
fd_item_get_transferred(fd_item item){
    assert(item != NULL);
    return item->transferred;
}

void
fd_item_set_relation(fd_item item, int i){
    item->related = i;
}

int
fd_item_get_relation(fd_item item){
    return item->related;
}

void
fd_item_visited(fd_item item){
    item->fst_time=false;
}

bool
fd_item_is_first_time(fd_item item){
    return item->fst_time;
}

void
fd_item_set_port(fd_item item, int aux){
    item->port = aux;
}

int
fd_item_get_port(fd_item item){
    return item->port;
}

/*
  Este es el destructor
*/
void
fd_item_destroy(fd_item item){
    assert(item != NULL);
    free(item->filename);
    item->filename=NULL;
    free(item->recv_str);
    item->recv_str=NULL;
    free(item);
    item = NULL;
}

/*
  ACA EMPIEZAN LAS FUNCIONES DE LISTA
*/

/*
  Constructor de lista
*/
fd_list
fd_list_create(void){
    struct sfd_list *list;

    list = calloc(1,sizeof(struct sfd_list));
    if (list == NULL){
        perror("malloc");
        return NULL;
    }    
    list->item = calloc(1,sizeof(fd_item*));
    if (list->item == NULL){
        perror("malloc");
        return NULL;
    }
    list->server = calloc(1,sizeof(fd_server*));
    if (list->server == NULL){
        perror("malloc");
        return NULL;
    }
    list->size = 0;
    list->server_size = 0;
    return list;
}

/*
  Aqui vamos agregando items a la lista de fd's
  le pasamos el fd, y el comando pedido, el fd es cargado
  en el ultimo lugar de la lista
*/
void
fd_list_add_fd(fd_list list, int fd){
    fd_item item;
    assert(list != NULL);
    assert(fd != 0);
    item = fd_item_create();
    fd_item_set_fd(item, fd);
    list->item = (fd_item*)realloc(list->item,\
                  sizeof(struct sfd_item)*((list->size)+1));
    list->item[list->size] = item;
    list->size = list->size + 1;
}

/*
  Obtenemos el fd
*/
int
fd_list_get_fd(fd_list list, int n){
    return fd_item_get_fd(list->item[n]);
}

void
fd_list_add_server_fd(fd_list list, int fd){
    fd_server server;
    assert(list != NULL);
    assert(fd != 0);
    server = fd_server_create();
    fd_server_set_fd(server, fd);
    list->server = (fd_server*)realloc(list->server,\
                  sizeof(struct sfd_server)*((list->server_size)+1));
    list->server[list->server_size] = server;
    list->server_size = list->server_size + 1;
}

/*
  Obtenemos el fd
*/
int
fd_list_get_server_fd(fd_list list, int n){
    return fd_server_get_fd(list->server[n]);
}

/*
  Seteamos el comando para el fd
*/
void
fd_list_set_cmd(fd_list list, int n, int cmd){
    assert(list != NULL);
    fd_item_set_cmd(list->item[n], cmd);
}

/*
  Obetenemos el comando con el que fue seteado el fd
*/
int
fd_list_get_cmd(fd_list list, int n){
    return fd_item_get_cmd(list->item[n]);
}

void
fd_list_set_server_cmd(fd_list list, int n, int cmd){
    assert(list != NULL);
    fd_server_set_cmd(list->server[n], cmd);
}

/*
  Obetenemos el comando con el que fue seteado el fd
*/
int
fd_list_get_server_cmd(fd_list list, int n){
    return fd_server_get_cmd(list->server[n]);
}

/*
  Con esta funcion sacamos el elemento n de la lista
*/
void
fd_list_remove(fd_list list, int n){
    assert(list != NULL);
    fd_item_destroy(list->item[n]);
    while (n < (list->size)-1){
        list->item[n] = list->item[n+1];
        n++;
    }
    if (list->size > 0){
        list->item[list->size-1] = NULL;
        list->size = list->size - 1;
    }
}

void
fd_list_server_remove(fd_list list, int n){
    assert(list != NULL);
    fd_server_destroy(list->server[n]);
    while (n < (list->server_size)-1){
        list->server[n] = list->server[n+1];
        n++;
    }
    if (list->server_size > 0){
        list->server[list->server_size-1] = NULL;
        list->server_size = list->server_size - 1;
    }
}

/*
  Con esta funcion devolvemos la ubicacion en la lista
  de un fd
*/
int
fd_list_search(fd_list list, int fd){
    int i = 0;
    assert(list != NULL);
    assert(fd != 0);
    for (i=0;i<list->size;i++){
        if (fd==fd_item_get_fd(list->item[i])){
            return i;
        }
    }
    return -1;
}

int
fd_list_server_search(fd_list list, int fd){
    int i = 0;
    assert(list != NULL);
    assert(fd != 0);
    for (i=0;i<list->server_size;i++){
        if (fd==fd_server_get_fd(list->server[i])){
            return i;
        }
    }
    return -1;
}

/*
  Obtenemos el item con indice n
*/
fd_item
fd_list_get_item(fd_list list, int n){
    assert(list != NULL);
    return list->item[n];
}

fd_server
fd_list_get_server(fd_list list, int n){
    assert(list != NULL);
    return list->server[n];
}

/*
  Cargamos un fd con el nombre del archivo pedido, donde comienza 
  y donde termina el pedido
*/
void
fd_list_add_file(fd_list list, int n, char* filename, int offset,\
                 int amount){
    assert(list != NULL);
    assert(filename != NULL);
    fd_item_set_filename(list->item[n], filename);
    fd_item_set_offset(list->item[n], offset);
    fd_item_set_amount(list->item[n], amount);
    fd_item_set_transferred(list->item[n], 0);
}

/*
  Obtenemos el nombre del archivo pedido por el fd ubicado en la posicion
  n de la lista
*/
char*
fd_list_get_filename(fd_list list, int n){
    assert(list != NULL);
    return fd_item_get_filename(list->item[n]);
}

/*
  Seteamos el filename del fd ubicado en la posicion n de la lista
*/
void
fd_list_set_filename(fd_list list, int n, char* filename){
    assert(list != NULL);
    assert(filename != NULL);
    fd_item_set_filename(list->item[n], filename);
}


void
fd_list_server_clear_file(fd_list list, int n){
    fd_server_clear_file(list->server[n]);
}

void
fd_list_server_set_file(fd_list list, int n, bstring file){
    fd_server_set_file(list->server[n], file);
}

bstring
fd_list_server_get_file(fd_list list, int n){
    return fd_server_get_file(list->server[n]);
}

/*
  Obtenemos lo recibido del fd ubicado en la posicion n de la lista
*/
char*
fd_list_get_recv_str(fd_list list, int n){
    assert(list != NULL);
    return fd_item_get_recv_str(list->item[n]);
}

/*
  Seteamos el filename del fd ubicado en la posicion n de la lista
*/
void
fd_list_add_recv_str(fd_list list, int n, char* string, int i){
    assert(list != NULL);
    assert(string != NULL);
    fd_item_add_recv_str(list->item[n], string, i);
}

void
fd_list_reset_recv_str(fd_list list, int n){
    assert(list != NULL);
    fd_item_reset_recv_str(list->item[n]);
}

char*
fd_list_get_server_recv_str(fd_list list, int n){
    assert(list != NULL);
    return fd_server_get_recv_str(list->server[n]);
}

/*
  Seteamos el filename del fd ubicado en la posicion n de la lista
*/
void
fd_list_add_server_recv_str(fd_list list, int n, char* string, int i){
    assert(list != NULL);
    assert(string != NULL);
    fd_server_add_recv_str(list->server[n], string, i);
}

void
fd_list_reset_server_recv_str(fd_list list, int n){
    assert(list != NULL);
    fd_server_reset_recv_str(list->server[n]);
}

/*
  Obtenemos el offset pedido en el fd ubicado en la posicion n de la lista
*/
int
fd_list_get_offset(fd_list list, int n){
    assert(list != NULL);
    return fd_item_get_offset(list->item[n]);
}

/*
  Seteamos el offset en el fd ubicado en la posicion n de la lista
*/
void
fd_list_set_offset(fd_list list, int n, int m){
    assert(list != NULL);
    fd_item_set_offset(list->item[n], m);
}

/*
  Obtenemos el amount del fd ubicado en la posicion n de la lista
*/
int
fd_list_get_amount(fd_list list, int n){
    assert(list != NULL);
    return fd_item_get_amount(list->item[n]);
}

/*
  Seteamos el amount en el fd ubicado en la posicion n de la lista
*/
void
fd_list_set_amount(fd_list list, int n, int m){
    assert(list != NULL);
    fd_item_set_amount(list->item[n], m);
}

/*
  Obtenemos el numero de fd's en la lista (tamaño de la lista)
*/
int
fd_list_size(fd_list list){
    assert(list != NULL);
    return list->size;
}

int
fd_list_server_size(fd_list list){
    assert(list != NULL);
    return list->server_size;
}

/*
  Seteamos el campo que informa si el fd ubicado en la posicion n de la lista,
  se finalizo de atender
*/
void
fd_list_set_finish(fd_list list, int n, bool b){
    assert(list != NULL);
    fd_item_set_atnd(list->item[n], b);
}

/*
  Obtenemos el campo que informa si el fd termino
*/
bool
fd_list_get_finish(fd_list list, int n){
    assert(list != NULL);
    return(fd_item_get_atnd(list->item[n]));

}

/*
  Seteamos la cantidad transferida del archivo en el fd ubicado
  en la posicion n de la lista
*/
void
fd_list_set_transferred(fd_list list, int n, int transferred){
    assert(list != NULL);
    fd_item_set_transferred(list->item[n], transferred);
}

/*
  Obtenemos la cantidad transferida del archivo en el fd ubicado
  en la posicion n de la lista
*/
int
fd_list_get_transferred(fd_list list, int n){
    assert(list != NULL);
    return fd_item_get_transferred(list->item[n]);
}

/*
  Seteamos si el fd ubicado en la posicion n de la lista termino de enviarnos
  todo el comando.
*/
void
fd_list_set_recv(fd_list list, int n, bool recv){
    assert(list != NULL);
    fd_item_set_recv(list->item[n], recv);
}

/*
  Preguntamos si el fd ubicado en la posicion n de la lista nos ha enviado
  el comando completo.
*/
bool
fd_list_get_recv(fd_list list, int n){
    assert(list != NULL);
    return fd_item_get_recv(list->item[n]);
}

void
fd_list_set_server_recv(fd_list list, int n, bool recv){
    assert(list != NULL);
    fd_server_set_recv(list->server[n], recv);
}

/*
  Preguntamos si el fd ubicado en la posicion n de la lista nos ha enviado
  el comando completo.
*/
bool
fd_list_get_server_recv(fd_list list, int n){
    assert(list != NULL);
    return fd_server_get_recv(list->server[n]);
}

void
fd_list_server_receive(fd_list list, int n){
    fd_server_receive(list->server[n]);
}

void
fd_list_server_send(fd_list list, int n){
    fd_server_send(list->server[n]);
}

void
fd_list_server_stop_receiving(fd_list list, int n){
    fd_server_stop_receiving(list->server[n]);
}

void
fd_list_server_not_send(fd_list list, int n){
    fd_server_not_send(list->server[n]);
}

bool
fd_list_server_should_receive(fd_list list, int n){
    return fd_server_should_receive(list->server[n]);
}

bool
fd_list_server_should_send(fd_list list, int n){
    return fd_server_should_send(list->server[n]);
}

void
fd_list_server_set_transferred(fd_list list, int n, int transferred){
    fd_server_set_transferred(list->server[n], transferred);
}

int
fd_list_server_get_transferred(fd_list list, int n){
    return fd_server_get_transferred(list->server[n]);
}

void
fd_list_server_set_metadata(fd_list list, int n, int metadata){
    fd_server_set_metadata(list->server[n], metadata);
}

int
fd_list_server_get_metadata(fd_list list, int n){
    return fd_server_get_metadata(list->server[n]);
}

void
fd_list_server_append_filename(fd_list list, int n, char* filename){
    fd_server_append_filename(list->server[n], filename);
}

char*
fd_list_server_get_filename_from_list(fd_list list, int n){
    return fd_server_get_filename_from_list(list->server[n]);
}

void
fd_list_server_swap_filename(fd_list list, int n){
    fd_server_swap_filename(list->server[n]);
}

void
fd_list_server_remove_filename_from_list(fd_list list, int n){
    fd_server_remove_filename_from_list(list->server[n]);
}

void
fd_list_server_set_relation(fd_list list, int n, int i){
    fd_server_set_relation(list->server[n], i);
}

int
fd_list_server_get_relation(fd_list list, int n){
    return fd_server_get_relation(list->server[n]);
}

void
fd_list_item_set_relation(fd_list list, int n, int i){
    fd_item_set_relation(list->item[n], i);
}

int
fd_list_item_get_relation(fd_list list, int n){
    return fd_item_get_relation(list->item[n]);
}

void
fd_list_item_visited(fd_list list, int n){
    fd_item_visited(list->item[n]);
}

bool
fd_list_is_first_time(fd_list list, int n){
    return fd_item_is_first_time(list->item[n]);
}

void
fd_list_set_item_port(fd_list list, int n, int aux){
    fd_item_set_port(list->item[n], aux);
}

int
fd_list_get_item_port(fd_list list, int n){
    return fd_item_get_port(list->item[n]);
}

void
fd_list_set_server_port(fd_list list, int n, int port){
    fd_server_set_port(list->server[n], port);
}

int
fd_list_get_server_port(fd_list list, int n){
    return fd_server_get_port(list->server[n]);
}

void
fd_list_set_server_response(fd_list list, int n, int response){
    fd_server_set_response(list->server[n], response);
}

int
fd_list_get_server_response(fd_list list, int n){
    return fd_server_get_response(list->server[n]);
}

int
fd_list_get_server_filenames_count(fd_list list, int n){
    return fd_server_get_filenames_count(list->server[n]);
}

void
fd_list_server_clear_new_file(fd_list list){
    int i=0;
    for (i=0;i<fd_list_server_size(list);i++){
        fd_server_clear_new_file(list->server[i]);
    }
}

void
fd_list_server_set_new_file(fd_list list, int i){
    fd_server_set_new_file(list->server[i]);
}

bool
fd_list_server_get_new_file(fd_list list, int i){
    return fd_server_get_new_file(list->server[i]);
}

void
fd_list_server_set_start_over(fd_list list, int i){
    fd_server_set_start_over(list->server[i]);
}

void
fd_list_server_clear_start_over(fd_list list, int i){
    fd_server_clear_start_over(list->server[i]);
}

bool
fd_list_server_should_start_over(fd_list list, int i){
    return fd_server_should_start_over(list->server[i]);
}

/*
  Destructor del tipo fd_list
*/
void
fd_list_destroy(fd_list list){
    int i=0;
    while(list->size!=0){
        fd_list_remove(list, i);
    }
    free(list->item);
    list->item = NULL;
    while(list->server_size!=0){
        fd_list_server_remove(list, 0);
    }
    free(list->server);
    list->server = NULL;

    free(list);
    list = NULL;
}
